home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Risc World 3
/
Risc World 3.iso
/
SOFTWARE
/
ISSUE6
/
PD
/
PDF
/
pdf
/
c++
/
Find
< prev
next >
Wrap
Text File
|
2003-02-14
|
8KB
|
288 lines
//--------------------------------------------------------------------------
//
// Copyright (c) 2002, Colin Granville
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// * The name Colin Granville may not be used to endorse or promote
// products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
//--------------------------------------------------------------------------
#include "Find.h"
#include "DocView.h"
#include "GuiWindow.h"
#include "GuiGadget.h"
#include "GuiTargets.h"
#include "TextOutputDev.h"
#include "GfxState.h"
#include "UserEvents.h"
#include "Document.h"
#include "guilib:gfx.h"
#include "strstream.h"
class TextOutputDevice : public TextOutputDev
{
public:
TextOutputDevice();
virtual ~TextOutputDevice() {};
double getHeight() {return height;}
virtual void startPage(int pageNum, GfxState *state);
private:
double height;
};
//*************************************************************************
TextOutputDevice::TextOutputDevice()
: TextOutputDev(0,0,0,0),
height(0)
{
}
//*************************************************************************
void TextOutputDevice::startPage(int pageNum, GfxState *state)
{
setDefaultCTM(state->getCTM());
GuiBBox bounds;
cvtUserToDev(state->getX1(),state->getY1(),&bounds.xmin,&bounds.ymin);
cvtUserToDev(state->getX2(),state->getY2(),&bounds.xmax,&bounds.ymax);
height=(double)(bounds.ymin-bounds.ymax);
TextOutputDev::startPage(pageNum,state);
}
//*************************************************************************
//*************************************************************************
//*************************************************************************
class Find
{
public:
Find();
~Find();
void aboutToBeShown(DocView& view);
void viewClosed(DocView& view);
private:
GuiWindow window;
GuiWritableField text;
GuiOptionButton fromStart;
GuiButton notFound;
GuiWindow nextWindow;
GuiButton nextStatus;
GuiActionButton nextButton;
DocView* view;
TextOutputDevice outDev;
int page;
string searchString;
bool top;
double fromx,fromy;
void showPageStatus();
GUI_DECLARE_EVENT_TARGETS(Find);
GuiNullTarget nullEventTarget;
void nullEvent();
GuiNullTarget nextHiddenTarget;
void nextHidden();
GuiToolboxTarget doFindTarget;
Claim doFind(GuiToolboxEvent&,const GuiIdBlock&);
GuiToolboxTarget findNextTarget;
Claim findNext(GuiToolboxEvent&,const GuiIdBlock&);
};
//*************************************************************************
Find::Find()
: window("Find"),
text(window,1),
fromStart(window,2),
notFound(window,5),
nextWindow("FindNext"),
nextStatus(nextWindow,5),
nextButton(nextWindow,2),
view(0),
doFindTarget(&window,User_Find,this,Find::doFind),
findNextTarget(&nextWindow,User_FindNext,this,Find::findNext)
{
}
//*************************************************************************
Find::~Find() {}
//*************************************************************************
void Find::aboutToBeShown(DocView& v)
{
view=&v;
notFound.setValue("");
fromStart.set(0);
}
//*************************************************************************
void Find::viewClosed(DocView& v)
{
if (&v==view)
{
view=0;
window.hide();
nextWindow.hide();
}
}
//*************************************************************************
Claim Find::doFind(GuiToolboxEvent&,const GuiIdBlock&)
{
searchString=text.getValue();
if (searchString.size()==0) return CLAIM;
page=(fromStart.isOn()? 1 : view->getPage());
nullEventTarget(this,Find::nullEvent);
nextHiddenTarget(this,Find::nextHidden);
nextWindow.showAsMenuCentred(window,&window);
nextButton.fade(1);
showPageStatus();
top=1;
return CLAIM;
}
//*************************************************************************
void Find::nextHidden()
{
if (!nextWindow.isShowing())
{
nextHiddenTarget.destroy();
nullEventTarget.destroy();
if (view) view->clearHighlight();
}
}
//*************************************************************************
void Find::nullEvent()
{
int pageCount=view->getDocument().getPageCount();
if (view==0 || (page<1 || page>pageCount))
{
nullEventTarget.destroy();
return;
}
if (top) view->getDocument().getPage(page,&outDev,DrawOutputDevice::DPI,0);
Unicode* unicode=new Unicode[searchString.size()];
int i;
if (!unicode)
{
nullEventTarget.destroy();
return;
}
unsigned char*s=(unsigned char*)searchString.c_str();
for (i=0;i<searchString.size();i++) unicode[i]=s[i];
double xmax,ymax;
if (outDev.findText(unicode,searchString.size(),
top,1,&fromx,&fromy,&xmax,&ymax))
{
HighlightBBox box;
box.xmin=fromx;
box.ymin=outDev.getHeight()-ymax;
box.xmax=xmax;
box.ymax=outDev.getHeight()-fromy;
fromx=xmax;
fromy=ymax;
top=0;
nullEventTarget.destroy();
nextStatus.setValue("Found");
nextButton.fade(0);
view->setHighlight(page,box);
}
else
{
page++;
top=1;
if (page>pageCount)
{
nextStatus.setValue("Not Found");
}
else
{
showPageStatus();
}
}
delete [] unicode;
}
//*************************************************************************
void Find::showPageStatus()
{
char buf[32];
ostrstream out(buf,sizeof(buf));
out << "Searching page: " << page;
nextStatus.setValue(out.str());
}
//*************************************************************************
Claim Find::findNext(GuiToolboxEvent&,const GuiIdBlock&)
{
if (view)
{
nullEventTarget(this,Find::nullEvent);
nextButton.fade(1);
}
return CLAIM;
}
//*************************************************************************
void find(DocView& view,bool ViewClosed)
{
static Find f;
if (ViewClosed)
f.viewClosed(view);
else
f.aboutToBeShown(view);
}